package models

import (
	"context"
	"time"
)

// 红包记录类型常量
const (
	RedPacketTypeIncome  = 1 // 收入
	RedPacketTypeExpense = 2 // 支出
)

// 红包来源常量
const (
	RedPacketSourceComment = "comment" // 好评
	RedPacketSourceInvite  = "invite"  // 邀请
	RedPacketSourceOrder   = "order"   // 下单返现
	RedPacketSourceSign    = "sign"    // 签到
	RedPacketSourceUse     = "use"     // 使用
)

// 红包记录状态常量
const (
	RedPacketStatusNormal   = 1 // 正常
	RedPacketStatusRefunded = 2 // 已退回
)

// RedPacketRecord 红包流水表
type RedPacketRecord struct {
	Id         int64     `json:"id" xorm:"pk autoincr"`
	UserId     int64     `json:"user_id" xorm:"not null comment('用户ID') index"`
	Type       int       `json:"type" xorm:"tinyint(4) not null comment('类型:1收入 2支出')"`
	Amount     float64   `json:"amount" xorm:"decimal(10,2) not null comment('金额')"`
	Balance    float64   `json:"balance" xorm:"decimal(10,2) not null comment('变动后余额')"`
	Source     string    `json:"source" xorm:"varchar(50) not null comment('来源') index"`
	SourceId   string    `json:"source_id" xorm:"varchar(50) null comment('来源ID') index"`
	Title      string    `json:"title" xorm:"varchar(100) not null comment('流水标题')"`
	Remark     string    `json:"remark" xorm:"varchar(255) null comment('备注')"`
	Status     int       `json:"status" xorm:"tinyint(4) not null default 1 comment('状态:1正常 2已退回')"`
	ExpireTime time.Time `json:"expire_time" xorm:"datetime null comment('过期时间')"`
	UpdateTime time.Time `json:"update_time" xorm:"not null updated comment('更新时间')"`
	CreateTime time.Time `json:"create_time" xorm:"not null created comment('创建时间')"`
}

// TableName 表名
func (RedPacketRecord) TableName() string {
	return "red_packet_record"
}

// CreateRedPacketRecord 创建红包流水记录
func CreateRedPacketRecord(ctx context.Context, record *RedPacketRecord) error {
	session := getSession(ctx)
	defer session.Close()

	// 开启事务
	if err := session.Begin(); err != nil {
		return err
	}

	// 获取用户红包账户
	account, err := GetRedPacketAccount(ctx, record.UserId)
	if err != nil {
		session.Rollback()
		return err
	}

	// 更新账户余额
	if err := account.UpdateBalance(ctx, record.Amount, record.Type == RedPacketTypeIncome); err != nil {
		session.Rollback()
		return err
	}

	// 设置变动后余额
	record.Balance = account.Balance

	// 插入流水记录
	if _, err := session.Insert(record); err != nil {
		session.Rollback()
		return err
	}

	return session.Commit()
}

// GetRedPacketRecords 获取用户红包流水记录
func GetRedPacketRecords(ctx context.Context, userId int64, page, pageSize int) ([]*RedPacketRecord, int64, error) {
	var records []*RedPacketRecord
	count, err := FindByPage(ctx, &records, page, pageSize, "user_id = ?", userId)
	return records, count, err
}

// RefundRedPacketRecord 退回红包
func RefundRedPacketRecord(ctx context.Context, id int64) error {
	session := getSession(ctx)
	defer session.Close()

	// 开启事务
	if err := session.Begin(); err != nil {
		return err
	}

	// 获取流水记录
	var record RedPacketRecord
	exists, err := session.ID(id).Get(&record)
	if err != nil {
		session.Rollback()
		return err
	}
	if !exists {
		session.Rollback()
		return ErrRecordNotFound
	}

	// 检查状态
	if record.Status != RedPacketStatusNormal {
		session.Rollback()
		return ErrRecordStatusInvalid
	}

	// 获取用户红包账户
	account, err := GetRedPacketAccount(ctx, record.UserId)
	if err != nil {
		session.Rollback()
		return err
	}

	// 更新账户余额(收入变支出,支出变收入)
	if err := account.UpdateBalance(ctx, record.Amount, record.Type == RedPacketTypeExpense); err != nil {
		session.Rollback()
		return err
	}

	// 更新流水状态
	record.Status = RedPacketStatusRefunded
	if _, err := session.ID(id).Update(&record); err != nil {
		session.Rollback()
		return err
	}

	return session.Commit()
}
